package com.jun.common.redis.utils;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author yuejun.li
 * @date 2024/7/18 14:56:50
 * 分布式ID工具类
 */
public class RedisGenerateIDUtils {

    private RedisTemplate<String, Object> redisTemplate;

    public RedisGenerateIDUtils(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 获取全局唯一ID
     * @param key 业务标识key
     */
    public String getId(String key) {
        //当前年月日
        String currentDate = getYYYYMMDD();
        //获取对应业务自增序列
        String cacheKey = key + ":" + currentDate;
        Long incr = redisTemplate.opsForValue().increment(cacheKey);
        //当前年月日+4位编码
        String resultID = currentDate + String.format("%04d",incr);
        return resultID;
    }

    /**
     * 获取多个全局唯一ID
     * @param key 业务标识key
     * @param size 获取size个id
     */
    public List<String> getIds(String key,int size) {
        if(size < 1){
            return Collections.emptyList();
        }
        //当前年月日
        String currentDate = getYYYYMMDD();
        //获取对应业务自增序列
        ValueOperations<String, Object> operations = redisTemplate.opsForValue();
        String cacheKey = key + ":" + currentDate;
        Long beginIncr = operations.increment(cacheKey);
        Long endIncr = operations.increment(cacheKey,size);

        List<String> result = new ArrayList(size);
        for(long i = beginIncr; i < endIncr; i++) {
            //当前年月日+4位编码
            String resultID = currentDate + String.format("%04d",i);
            result.add(resultID);
        }
        return result;
    }

    /**
     * 获取当前YYYYMMDD格式年月日
     */
    private String getYYYYMMDD() {
        LocalDate currentDate = LocalDate.now();
        int year = currentDate.getYear();
        int month = currentDate.getMonthValue();
        int day = currentDate.getDayOfMonth();
        return "" + year + month + day;
    }
}
